using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace KLib.Utilities
{
    #region FPSPosition
    public enum FPSPosition
	{
        TopLeft      = 0,
        TopCenter    = 1,
        TopRight     = 2,
        BottomLeft   = 10,
        BottomCenter = 11,
        BottomRight  = 12
	}
	#endregion

    /// <summary>
    /// Draws the FPS (Frames per Second) to the screeen
    /// </summary>
    public class FPS : Microsoft.Xna.Framework.DrawableGameComponent
    {
        #region Fields
        private ContentManager content;

        private SpriteBatch spriteBatch;
        private SpriteFont font;

        private FPSPosition fpsPosition = FPSPosition.TopLeft;
        private Vector2 position = Vector2.One*5;

        private float frameRate =0;
        private int frameCount = 0;
        TimeSpan elapsedTime = TimeSpan.Zero;
        private int width;
        private int height;
        #endregion

        #region Properties
        /// <summary>
        /// Gets the FrameRate
        /// </summary>
        public float FrameRate
        {
            get { return frameRate; }
        }

        /// <summary>
        /// Gets or sets the Position of the FPS display on the screen
        /// </summary>
        public FPSPosition Position
        {
            get { return fpsPosition; }
            set
            {
                width = GraphicsDevice.Viewport.Width;
                height = GraphicsDevice.Viewport.Height;
                fpsPosition = value;
           
                int xLoc;
                //It is on the bottom, See FPSPosition values for details
                if ((int)fpsPosition >= 10)
                {
                    position.Y = position.Y = GraphicsDevice.PresentationParameters.BackBufferHeight - (height * 0.08f) - font.MeasureString("F").Y;
                    xLoc = (int)fpsPosition - 10;
                }
                //It is on the top
                else
                {
                    position.Y = (height * 0.08f);
                    xLoc = (int)fpsPosition;
                }

                //Find the x position from the remaining data
                switch (xLoc)
                {
                    case 0:
                        position.X = (width *0.08f);
                        break;
                    case 1:
                        position.X = GraphicsDevice.PresentationParameters.BackBufferWidth / 2 - font.MeasureString("FPS: 000").X/2;
                        break;
                    case 2:
                        position.X = GraphicsDevice.PresentationParameters.BackBufferWidth - (width * 0.08f) - font.MeasureString("FPS: 000").X;
                        break;
                }

            }
        }
        #endregion

        #region Initialization
        public FPS(Game game)
            : base(game)
        {
            content = new ContentManager(game.Services,"Content");
        }

        public override void Initialize()
        {
            this.DrawOrder = int.MaxValue;
            base.Initialize();
        }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            font = content.Load<SpriteFont>("Fonts/FPSFont");
            Position = FPSPosition.TopLeft;
            base.LoadContent();
        }
        #endregion

        #region Methods
        public override void Update(GameTime gameTime)
        {
            elapsedTime += gameTime.ElapsedGameTime;
            if (elapsedTime > TimeSpan.FromSeconds(1))
            {
                elapsedTime -= TimeSpan.FromSeconds(1);
                frameRate = frameCount;
                frameCount = 0;
            }

            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            frameCount++;
            string fps = string.Format("FPS: {0}", frameRate);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
            spriteBatch.DrawString(font, fps, position + Vector2.One, Color.Black);
            spriteBatch.DrawString(font, fps, position, Color.Yellow);
            spriteBatch.End();
            base.Draw(gameTime);
        }
        #endregion
    }
}